import json
import re
import json_tools
import pinyin
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render, redirect

from myapp.models import *
from myapp.DIY_do_step import *
from myapp.DIY_build import *

# 创建一个 工具
from myapp.views import power, useCount_write

# 添加自定义工具
def add_diy_tool(request):
    userid = request.user.id
    # print(userid)
    count = len(DB_DIY_tools.objects.filter(owner=userid)) + 1
    new_tool = DB_DIY_tools.objects.create(name="自定义工具%s" % count, owner=str(userid))
    return redirect('/DIY_tools/%s/' % new_tool.id)  # 新增后同时跳转进新增的自定义工具页


# 进入自定义工具页面
def DIY_tools(request, tid):
    res = {}  # 前端不能直接使用queryset类型数据，要用字典类型传给前端调用
    res["tool"] = DB_DIY_tools.objects.filter(id=tid)[0]  # filter 得到的是个querySet，如果是单个对象需要提取第0个元素
    res["steps"] = DB_DIY_steps.objects.filter(tool_id=tid).order_by("order")

    if res["tool"].owner == str(request.user.id):
        # print(res["tool"].owner, str(request.user.id))
        res["edit"] = "1"
    else:
        res["edit"] = '0'

    # 新增加要带的变量名
    res["all_inputs"] = json.dumps(eval(res["tool"].all_inputs))
    print(res["all_inputs"])
    return render(request, 'DIY_tools/diy_tool.html', res)


#  新增diy步骤
def add_DIY_step(request, tid):
    count = len(DB_DIY_steps.objects.filter(tool_id=tid))  # 把order 设置为10的倍数，这样可以随意在每个步骤的前后插入新的步骤
    DB_DIY_steps.objects.create(tool_id=tid, order=(count + 1) * 10, name="新增第%s步骤（待设置)" % ((count + 1) * 10))

    return redirect("/DIY_tools/%s/" % tid)


# 菜单获取自定义工具列表
def get_div_tools_list(request):
    ret = {}
    ret["tool_list"] = list(DB_DIY_tools.objects.all().values())
    return JsonResponse(ret)


# 保存自定义工具标题和描述
def DIY_tools_save_NameAndDes(request):
    tool_name = request.GET.get("tool_name")
    tool_des = request.GET.get("tool_des")

    # print(tool_name, tool_des)

    #  保存到数据库，发现没有传工具id，再回前端js去补参数

    tool_id = request.GET.get("tool_id")
    # print(tool_id)
    # 更新数据
    DB_DIY_tools.objects.filter(id=tool_id).update(name=tool_name, des=tool_des)

    return HttpResponse("")


# 增加输入
def DIY_tools_add_input(request):
    tool_id = request.GET.get("tool_id")
    which = request.GET.get("which")
    # all_inputs = DB_DIY_tools.objects.filter(id=tool_id)[0].all_inputs # filter 得到的是一个querySet列表，无法直接取值
    tools = DB_DIY_tools.objects.filter(id=tool_id)  # 建议分开写，防止后面还要用到重复查库
    all_inputs = tools[0].all_inputs
    # print(all_inputs)
    # 整合all_inputs
    if which == 'text':
        new_input = {"type": which, "des": "-", "need_user": True, "default_value": "", "help_text": "请在此输入...",
                     "par_name": ""}
    elif which == 'radio':
        new_input = {"type": which, "des": "-","data": [{"des": "", "value": "", "chose": True, "filter_id":""}, {"des": "", "value": "", "chose": True, "filter_id":""}],"par_name": ""}

    else:
        new_input = {"type": which, "des": "-","data": [{"des": "", "value": "", "chose": True}, {"des": "", "value": "", "chose": True}],"par_name": ""}

    all_inputs = eval(all_inputs)  # 先把"[]" 转为[]
    all_inputs.append(new_input)
    all_inputs = str(all_inputs)

    tools.update(all_inputs=all_inputs)  # 更新all_inputs
    return HttpResponse("")



# 拿到最新的all_inputs
def get_DIY_tools_all_inputs(request):
    tool_id = request.GET['tool_id']
    all_inputs = DB_DIY_tools.objects.filter(id=tool_id)[0].all_inputs
    res = {"all_inputs": eval(all_inputs)}
    return HttpResponse(json.dumps(res), content_type='application/json')


# 删除一个输入
def DIY_tools_del_input(request):
    tool_id = request.GET.get("tool_id")
    input_index = request.GET.get("input_index")

    tool = DB_DIY_tools.objects.filter(id=tool_id)[0]
    # 拿出来的是一个大字符串
    all_inputs = tool.all_inputs
    print(f"删除前 all_inputs===》{all_inputs}")
    all_inputs = eval(all_inputs)
    # input_index 是一个字符串，要转成整型
    del all_inputs[int(input_index)]
    print(f"删除后  all_inputs===》{all_inputs}")

    all_inputs = str(all_inputs)
    tool.all_inputs = all_inputs
    tool.save()

    return HttpResponse("")


# 保存一个输入
def DIY_tools_save_input(request):
    tool_id = request.GET.get("tool_id")
    input_index = request.GET.get("input_index")
    s2_input = request.GET.get("s2_input")

    tool = DB_DIY_tools.objects.filter(id=tool_id)[0]
    # 拿出来的是一个大字符串
    all_inputs = tool.all_inputs
    all_inputs = eval(all_inputs)
    # all_inputs[int(input_index)] = s2_input   # 这里直接这样写，数据库里更新的时候会存字符串进去，s2_input 从前端传过来不是一个字典，而我们后端大字符串里存的都是字典
    # all_inputs[int(input_index)] = eval(s2_input)    eval 无法解析前端传过来的true  ,参考test5.py
    # all_inputs[int(input_index)] = json.loads(s2_input)

    tmp_input = json.loads(s2_input)
    # 如果没有设置par_name, 则后台根据des自动生成一个
    if not tmp_input["par_name"]:
        tmp_input["par_name"] = pinyin.get_initial(tmp_input["des"]).replace(" ", '')

    all_inputs[int(input_index)] = tmp_input
    all_inputs = str(all_inputs)
    tool.all_inputs = all_inputs
    tool.save()

    return HttpResponse("")


# 获取步骤数据
def DIY_tools_get_step(request):
    step_id = request.GET.get("step_id")
    data = list(DB_DIY_steps.objects.filter(id=step_id).values())[0]
    # print(data)
    res = {"res": data}
    return HttpResponse(json.dumps(res),content_type="application/json")

    ...


# 保存步骤数据
def DIY_tools_save_step(request,sid):
    tool_id = DB_DIY_steps.objects.filter(id=sid)[0].tool_id
    step_data = request.POST.dict()
    print(step_data)
    # 进行checkbox的处理
    for i in ['ifdo','request_cert','request_proxy','request_sign']:
        if step_data.get(i,False) == False:
            step_data[i] = False
        else:
            step_data[i] = True
    DB_DIY_steps.objects.filter(id=sid).update(**step_data)
    return redirect('/DIY_tools/%s/'%tool_id)

# 实现diff工具
def tool_diff_play(request):
    useCount_write("diff工具")
    try:
        tool_diff_old = json.loads(request.GET['tool_diff_old'])
        tool_diff_new = json.loads(request.GET['tool_diff_new'])
    except Exception as e:
        return HttpResponse('输入不符合json规范，异常字符位置：'+str(e))
    res = json_tools.diff(tool_diff_old,tool_diff_new)
    return HttpResponse(res)

# 运行正则检查工具
@power('diy_tools')
def tool_recheck_play(request):
    useCount_write("正则")
    tool_recheck_exp = request.GET['tool_recheck_exp']
    tool_recheck_old = request.GET['tool_recheck_old']
    res = re.findall(tool_recheck_exp,tool_recheck_old)
    return HttpResponse(str(res))

# 删除自定义工具步骤
def del_DIY_step(request, sid):
    step = DB_DIY_steps.objects.filter(id=sid)
    tool_id = step[0].tool_id
    step.delete()
    return  redirect("/DIY_tools/" + tool_id + "/")


# 获取工具日志
def DIY_tools_get_log(request):
    step_id = request.GET['step_id']
    log = DB_DIY_steps.objects.filter(id=step_id)[0].log
    res = '【日志】上次执行详细信息如下：\n' + log
    return HttpResponse(res)

# 删除日志
def DIY_tools_del_log(request,tid):
    DB_DIY_tools.objects.filter(id=tid).update(log='')
    # a 标签的路由必须要用重定向返回
    return redirect('/DIY_tools/'+tid+'/')

# 获取该步骤可用变量
def DIY_tools_get_variable_log(request):
    step_id = request.GET['step_id']
    step = DB_DIY_steps.objects.filter(id=step_id)[0]
    tool_id = step.tool_id
    tool = DB_DIY_tools.objects.filter(id=tool_id)[0]
    # 新建res
    res = '【变量】目前可用变量名如下：\n'
    # 拿到工具下的用户输入变量
    all_inputs = eval(tool.all_inputs) # all_inputs 从数据库里取的值是字符串
    for i in all_inputs:
        res += i["des"] + ":" + i["par_name"] + "\n"

    # 拿到此步骤执行顺序 之前 的步骤所产生的临时动态变量名（比较繁琐）
    now_order = step.order
    before_steps = DB_DIY_steps.objects.filter(tool_id=tool_id).filter(order__lt=now_order) # 小于当前步骤的步骤s
    for i in before_steps:
        # print(i.name)
        res += i.name+ "提取的变量" +' : '
        sql_extract_index = i.sql_extract_index
        res += '  '.join([e.split('=')[0].rstrip() for e in sql_extract_index.split('|||')]) + '  '

        linux_extract_re = i.linux_extract_re
        res += '  '.join([e.split('=')[0].rstrip() for e in linux_extract_re.split('|||')])+ '  '

        request_extract_re = i.request_extract_re
        res += '  '.join([e.split('=')[0].rstrip() for e in request_extract_re.split('|||')])+ '  '

        request_extract_path = i.request_extract_path
        res += '  '.join([e.split('=')[0].rstrip() for e in request_extract_path.split('|||')])+ '  '

        res += '\n'
        print(res)
    return HttpResponse(res)

# 自定义工具变更模式
def change_DIY_model(request, tid):
    # 改的这个字段必须包含旧的数据才能保证还可以切回原用户
    # 修改DB_DIY_tools 里面的创建人， 可以添加几个字符或者符号，然后切换模式的时候 加  或  减 这些符号

    # 判断当前模式
    nowOnwer = DB_DIY_tools.objects.filter(id=tid)[0].owner

    if "---" in nowOnwer: # 说明是变异状态， 此模式下所有人进来都是普通使用模式
        # 判断权限
        if str(request.user.id) == nowOnwer.split("---")[0]:
            DB_DIY_tools.objects.filter(id=tid).update(owner = nowOnwer.split("---")[0])  # 去掉---变成正常模式

    else: # 说明是正常状态， 使用模式和编辑模 式都正常
        # 判断权限
        if str(request.user.id) == nowOnwer:
            DB_DIY_tools.objects.filter(id=tid).update(owner=nowOnwer + "---")

    return redirect(f"/DIY_tools/{tid}/")


# 筛选自定义步骤
def DIY_get_steps(tool_id, user_data):
    # user_data 里存的数据才知道用户到底选了哪个，是不是要过滤
    all_steps = DB_DIY_steps.objects.filter(tool_id=tool_id).order_by("order")
    all_inputs = eval(DB_DIY_tools.objects.filter(id=tool_id)[0].all_inputs)
    del_filter = []
    for ai in all_inputs:
        if ai["type"] in ["radio"]:
            for d in ai['data']:
                if d["filter_id"] not in ["", " ", None, False]:
                    par_name = ai["par_name"]
                    par_value = d['value']
                    if user_data[par_name] == par_value: # 说明过滤中了规则
                        del_filter.append(d["filter_id"])

    res_steps = []
    # 添加正常步骤进去
    for i in all_steps:
        if i.filter_id not in del_filter:
            res_steps.append(i)

    return res_steps # 应该是一个列表


# 自定义工具运行
def DIY_tools_run(request):
    tool_id = request.GET.get("tool_id")
    user_data = request.GET.get("user_data")
    # print(user_data)
    # print(type(user_data))   str  此时是一个json字符串
    user_data = json.loads(user_data)   # 转位json对象
    # print(user_data)

    useCount_write(DB_DIY_tools.objects.filter(id=tool_id)[0].name) # 统计次数
    # 获取步骤
    steps = DIY_get_steps(tool_id, user_data)
    # print(steps)
    #  业务层真是构造
    res = build(user_data, steps)

    return HttpResponse(json.dumps(res), content_type='application/json')
